package org.red_cross_service.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * 时间工具类，提供常用的时间操作和转换功能
 * <p>
 * 本工具类主要用于处理以下场景：
 * - 获取当前时间（支持LocalDateTime和Date两种格式）
 * - 时间格式化与解析
 * - 不同时间类型之间的转换
 * - 时间的加减操作
 * - 计算时间差值
 * </p>
 * 
 * @author zxs
 * @version 1.0
 * @since 2025-06-07
 */
public class TimeUtils {

    // 默认时间格式
    private static final String DEFAULT_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /**
     * 获取当前时间（java.time.LocalDateTime）
     * 
     * @return 当前时间的LocalDateTime对象
     * @example
     * LocalDateTime now = TimeUtils.getCurrentLocalDateTime();
     */
    public static LocalDateTime getCurrentLocalDateTime() {
        return LocalDateTime.now();
    }

    /**
     * 获取当前时间（java.util.Date）
     */
    public static Date getCurrentDate() {
        return new Date();
    }

    /**
     * 格式化时间（java.time.LocalDateTime）
     *
     * @param time      需要格式化的LocalDateTime对象
     * @param formatStr 格式化模式字符串，如果为空则使用默认格式"yyyy-MM-dd HH:mm:ss"
     * @return 格式化后的时间字符串
     * @throws DateTimeException 如果格式化过程中发生错误
     * @example
     * String formattedTime = TimeUtils.formatLocalDateTime(LocalDateTime.now(), "yyyy-MM-dd");
     */
    public static String formatLocalDateTime(LocalDateTime time, String formatStr) {
        if (formatStr == null || formatStr.isEmpty()) {
            formatStr = DEFAULT_FORMAT;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatStr);
        return time.format(formatter);
    }

    /**
     * 格式化时间（java.util.Date）
     *
     * @param date       Date 对象
     * @param formatStr  格式化字符串，默认为 "yyyy-MM-dd HH:mm:ss"
     * @return 格式化后的时间字符串
     */
    public static String formatDate(Date date, String formatStr) {
        if (formatStr == null || formatStr.isEmpty()) {
            formatStr = DEFAULT_FORMAT;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatStr);
        return date.toInstant()
                .atZone(ZoneId.systemDefault())
                .format(formatter);
    }

    /**
     * 将字符串转换为 LocalDateTime
     *
     * @param timeStr    时间字符串
     * @param formatStr  格式化字符串，默认为 "yyyy-MM-dd HH:mm:ss"
     * @return LocalDateTime 对象
     */
    public static LocalDateTime strToLocalDateTime(String timeStr, String formatStr) {
        if (formatStr == null || formatStr.isEmpty()) {
            formatStr = DEFAULT_FORMAT;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatStr);
        return LocalDateTime.parse(timeStr, formatter);
    }

    /**
     * 将字符串转换为 Date
     *
     * @param timeStr    时间字符串
     * @param formatStr  格式化字符串，默认为 "yyyy-MM-dd HH:mm:ss"
     * @return Date 对象
     */
    public static Date strToDate(String timeStr, String formatStr) {
        LocalDateTime localDateTime = strToLocalDateTime(timeStr, formatStr);
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 将 Date 转换为 LocalDateTime
     *
     * @param date Date 对象
     * @return LocalDateTime 对象
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        return date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
    }

    /**
     * 将 LocalDateTime 转换为 Date
     *
     * @param localDateTime LocalDateTime 对象
     * @return Date 对象
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 时间加减操作（LocalDateTime）
     *
     * @param time       LocalDateTime 对象
     * @param days       加减的天数
     * @param hours      加减的小时数
     * @param minutes    加减的分钟数
     * @param seconds    加减的秒数
     * @return 加减后的 LocalDateTime 对象
     */
    public static LocalDateTime addLocalDateTime(LocalDateTime time, long days, long hours, long minutes, long seconds) {
        return time.plusDays(days)
                .plusHours(hours)
                .plusMinutes(minutes)
                .plusSeconds(seconds);
    }

    /**
     * 时间加减操作（Date）
     *
     * @param date       Date 对象
     * @param days       加减的天数
     * @param hours      加减的小时数
     * @param minutes    加减的分钟数
     * @param seconds    加减的秒数
     * @return 加减后的 Date 对象
     */
    public static Date addDate(Date date, long days, long hours, long minutes, long seconds) {
        Instant instant = date.toInstant()
                .plusSeconds(days * 86400 + hours * 3600 + minutes * 60 + seconds);
        return Date.from(instant);
    }

    /**
     * 计算两个时间之间的差值（秒数）
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 两个时间之间的差值（秒数）
     */
    public static long getDurationInSeconds(LocalDateTime startTime, LocalDateTime endTime) {
        return Duration.between(startTime, endTime).getSeconds();
    }

    /**
     * 示例代码展示工具类的基本用法
     * 
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        // 示例用法
        LocalDateTime now = getCurrentLocalDateTime();
        System.out.println("当前时间 (LocalDateTime): " + formatLocalDateTime(now, null));

        Date nowDate = getCurrentDate();
        System.out.println("当前时间 (Date): " + formatDate(nowDate, null));

        LocalDateTime futureTime = addLocalDateTime(now, 1, 2, 30, 0);
        System.out.println("加1天2小时30分钟后的时间 (LocalDateTime): " + formatLocalDateTime(futureTime, null));

        Date futureDate = addDate(nowDate, 1, 2, 30, 0);
        System.out.println("加1天2小时30分钟后的时间 (Date): " + formatDate(futureDate, null));

        long duration = getDurationInSeconds(now, futureTime);
        System.out.println("时间差值（秒）: " + duration);
    }
}
